//================================================================================================================================
//
//  Copyright (c) 2015-2018 VisionStar Information Technology (Shanghai) Co., Ltd. All Rights Reserved.
//  EasyAR is the registered trademark or trademark of VisionStar Information Technology (Shanghai) Co., Ltd in China
//  and other countries for the augmented reality technology developed by VisionStar Information Technology (Shanghai) Co., Ltd.
//
//================================================================================================================================

package com.easyarlibrary.artools.ar;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.easyarlibrary.app.BaseAppConstant;
import com.easyarlibrary.util.LogUtil;

import java.util.ArrayList;
import java.util.HashSet;

import cn.easyar.CameraDeviceFocusMode;
import cn.easyar.CloudRecognizer;
import cn.easyar.CloudStatus;
import cn.easyar.FunctorOfVoidFromCloudStatus;
import cn.easyar.FunctorOfVoidFromCloudStatusAndListOfPointerOfTarget;
import cn.easyar.FunctorOfVoidFromPointerOfTargetAndBool;
import cn.easyar.ImageTracker;
import cn.easyar.Target;
import cn.easyar.TargetInstance;

import static com.easyarlibrary.app.AppInfo.cloud_key;
import static com.easyarlibrary.app.AppInfo.cloud_secret;
import static com.easyarlibrary.app.AppInfo.cloud_server_address;

public class CloudAR extends BaseAR {

    private String currName;
    private String currVideo;
    private CloudRecognizer cloud_recognizer;
    private Handler handler;

    public CloudAR(Handler handler) {
        this.handler = handler;
    }

    @Override
    protected void initCloud() {
        if (cloud_recognizer == null) {
            cloud_recognizer = new CloudRecognizer();
            cloud_recognizer.attachStreamer(streamer);
        }
        cloud_recognizer.open(cloud_server_address, cloud_key, cloud_secret, new FunctorOfVoidFromCloudStatus() {
            @Override
            public void invoke(int status) {
                if (status == CloudStatus.Success) {
                    Log.i("HelloAR", "CloudRecognizerInitCallBack: Success");
                } else if (status == CloudStatus.Reconnecting) {
                    Log.i("HelloAR", "CloudRecognizerInitCallBack: Reconnecting");
                } else if (status == CloudStatus.Fail) {
                    Log.i("HelloAR", "CloudRecognizerInitCallBack: Fail");
                } else {
                    Log.i("HelloAR", "CloudRecognizerInitCallBack: " + Integer.toString(status));
                }
            }
        }, new FunctorOfVoidFromCloudStatusAndListOfPointerOfTarget() {
            private HashSet<String> uids = new HashSet<String>();

            @Override
            public void invoke(int status, ArrayList<Target> targets) {
                if (status == CloudStatus.Success) {
                    Log.i("HelloAR", "CloudRecognizerCallBack: Success");
                } else if (status == CloudStatus.Reconnecting) {
                    Log.i("HelloAR", "CloudRecognizerCallBack: Reconnecting");
                } else if (status == CloudStatus.Fail) {
                    Log.i("HelloAR", "CloudRecognizerCallBack: Fail");
                } else {
                    Log.i("HelloAR", "CloudRecognizerCallBack: " + Integer.toString(status));
                }
                synchronized (uids) {
                    for (Target t : targets) {
                        if (!uids.contains(t.uid())) {
                            Log.i("HelloAR", "add cloud target: " + t.uid());
                            uids.add(t.uid());
                            trackers.get(0).loadTarget(t, new FunctorOfVoidFromPointerOfTargetAndBool() {
                                @Override
                                public void invoke(Target target, boolean status) {
                                    Log.i("HelloAR", String.format("load target (%b): %s (%d)", status, target.name(), target.runtimeID()));
                                }
                            });
                        }
                    }
                }
            }
        });
    }
    public void setCurrVideo(String currVideo) {
        this.currVideo = currVideo;
    }

    public void setCurrName(String currName) {
        this.currName = currName;
    }
    public void reSetCurrName() {
        currName = "";
    }
    public void resetCurrPath() {
        currVideo = "";
    }
    @Override
    public void dispose() {
        super.dispose();
        if (cloud_recognizer != null) {
            cloud_recognizer.dispose();
            cloud_recognizer = null;
        }
    }

    @Override
    public boolean start() {
        if (camera == null) {
            return false;
        }
        boolean status = true;
        status &= (camera != null) && camera.start();
        status &= (streamer != null) && streamer.start();
        status &= (cloud_recognizer != null) && cloud_recognizer.start();
        camera.setFocusMode(CameraDeviceFocusMode.Continousauto);
        for (ImageTracker tracker : trackers) {
            status &= tracker.start();
        }
        return status;
    }

    @Override
    public boolean stop() {
        boolean status = true;
        for (ImageTracker tracker : trackers) {
            status &= tracker.stop();
        }
        status &= (cloud_recognizer != null) && cloud_recognizer.stop();
        status &= (streamer != null) && streamer.stop();
        status &= (camera != null) && camera.stop();
        return status;
    }

    @Override
    protected void doResule(TargetInstance targetInstance) {
        String currTempName = targetInstance.target().name();
        if (!TextUtils.isEmpty(currName) && currName.equals(currTempName)) {
            return;
        }
        currName = currTempName;
        LogUtil.d("----识别结果----->" + targetInstance.target().name());
        Message msg = new Message();
        msg.obj = currName;
        msg.what = BaseAppConstant.HanlderWhat.HANDLE_WHAT_GETBOOKNAME_OK;
        //延迟200ms发送防止识别有误
        handler.sendMessageDelayed(msg, 200);
    }
}
